<template>
  <!-- 操作按钮 -->
  <el-card>
    <el-button type="primary" class="primary_btn" id="saveFlow">保存流程图</el-button>
    <el-button type="primary" class="primary_btn" id="exportImg">导出图片</el-button>
    <el-button type="primary" class="primary_btn" id="importJson">导入JSON数据</el-button>
  </el-card>
  <!-- 用于显示 LogicFlow 图表的容器 -->
  <div id="container"></div>
  <!-- 弹窗 -->
  <el-dialog v-model="dialogFormVisible" title="输入JSON数据" width="500">
    <el-input
        v-model="jsonData"
        :rows="10"
        type="textarea"
        placeholder="Please input"
    />
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="confirm">确认</el-button>
      </div>
    </template>
  </el-dialog>
  <!-- 节点属性设置抽屉 -->
  <el-drawer v-model="drawer2" :direction="direction">
    <template #header>
      <h4>属性设置</h4>
    </template>
    <template #default>
      <div>
        <el-form
            ref="userFormRef"
            :model="formData"
            label-width="120px"
        >
          <el-form-item label="节点ID" prop="userId">
            <el-input :value="formData.nodeId" :readonly="true"/>
          </el-form-item>
          <el-form-item label="节点类型" prop="nodeType">
            <el-input ref="nodeType" name="nodeType" v-model="formData.nodeType" :readonly="true"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.USER_TASK" label="节点名称" prop="nodeName">
            <el-input ref="nodeName" name="nodeName" v-model="formData.nodeName" placeholder="请输入节点名称"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.USER_TASK" label="受让人" prop="assignee">
            <el-input ref="assignee" name="assignee" v-model="formData.assignee" placeholder="请输入受让人"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.USER_TASK" label="候选人" prop="candidateUsers">
            <el-input ref="candidateUsers" name="candidateUsers" v-model="formData.candidateUsers"
                      placeholder="请输入候选人"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.USER_TASK" label="表单KEY" prop="formKey">
            <el-input ref="formKey" name="formKey" v-model="formData.formKey" placeholder="请输入表单KEY"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.USER_TASK" label="任务创建监听器" prop="taskListener">
            <el-input ref="taskListener" name="taskListener" v-model="formData.taskListener"
                      placeholder="请输入任务创建监听器"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.FLOW_EDGE" label="FROM节点" prop="targetRef">
            <el-input ref="targetRef" name="targetRef" v-model="formData.sourceNodeId" :readonly="true"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.FLOW_EDGE" label="TO节点" prop="targetRef">
            <el-input ref="targetRef" name="targetRef" v-model="formData.targetNodeId" :readonly="true"/>
          </el-form-item>
          <el-form-item v-if="formData.nodeType == FlowNodeTypeEnum.FLOW_EDGE" label="表达式" prop="flowConditions">
            <el-input ref="flowConditions" name="flowConditions" v-model="formData.condition"/>
          </el-form-item>
        </el-form>
      </div>
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button @click="cancelDrawer">取消</el-button>
        <el-button type="primary" @click="confirmDrawer">确认</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script lang="ts" setup>
import '@logicflow/core/dist/index.css'
import {onMounted} from 'vue'
import "@logicflow/core/lib/style/index.css";
import "@logicflow/extension/lib/style/index.css";
import initLogicFlow from "./MyLogicFlow";
import type {DrawerProps} from 'element-plus'
import {ElInput} from 'element-plus'
import {NodeAttrForm} from '@/api/flow/model'
import {FlowNodeTypeEnum} from "@/enums/FlowNodeTypeEnum"
import {LogicFlow} from "@logicflow/core"
import NodeData = LogicFlow.NodeData;
import EdgeData = LogicFlow.EdgeData;

// 用户表单数据
let formData = reactive<NodeAttrForm>({});

const dialogFormVisible = ref(false)
const jsonData = ref("")
const myLf = ref<any>(null)
const drawer2 = ref(false)
const direction = ref<DrawerProps['direction']>('rtl')
// 弹窗取消
const cancel = () => {
  dialogFormVisible.value = false
  jsonData.value = ""
}
// 弹窗确认
const confirm = () => {
  const jsonStr = jsonData.value
  cancel()
  const graphData = JSON.parse(jsonStr)
  myLf.value.render(graphData);
}
// 抽屉取消
const cancelDrawer = () => {
  drawer2.value = false
}
// 抽屉确认
const confirmDrawer = () => {
  drawer2.value = false
  console.log("抽屉确认1", formData)
  // 保存节点属性
  const node = myLf.value.getDataById(formData.nodeId)
  node.text
  myLf.value.updateAttributes(formData.nodeId, {
    text: {
      ...node.text,
      value: formData.nodeName
    },
    properties: {
      ...node.properties,
      assignee: formData.assignee,
      candidateUsers: formData.candidateUsers,
      formKey: formData.formKey,
      taskListener: formData.taskListener,
      sourceNodeId: formData.sourceNodeId,
      targetNodeId: formData.targetNodeId,
      condition: formData.condition,
    }
  })
}

// 定义图表数据，包含节点和边
const data = {
  nodes: []
}

// 初始化节点属性表单数据
const initFormData = (nodeData: NodeData) => {
  formData =reactive<NodeAttrForm>({})
  console.log("初始化表单数据", nodeData)
  formData.nodeId = nodeData.id
  formData.nodeType = nodeData.type
  formData.nodeName = nodeData.text?.value
  formData.assignee = nodeData.properties?.assignee
  formData.candidateUsers = nodeData.properties?.candidateUsers
  formData.formKey = nodeData.properties?.formKey
  formData.taskListener = nodeData.properties?.taskListener
  formData.sourceNodeId = nodeData.properties?.sourceNodeId
  formData.targetNodeId = nodeData.properties?.targetNodeId
}
const initFormData2 = (nodeData: EdgeData) => {
  formData =reactive<NodeAttrForm>({})
  console.log("初始化表单数据", nodeData)
  formData.nodeId = nodeData.id
  formData.nodeType = nodeData.type
  formData.sourceNodeId = nodeData.sourceNodeId
  formData.targetNodeId = nodeData.targetNodeId
  formData.condition = nodeData.properties?.condition
}

// 在组件挂载时执行
onMounted(() => {
  // 创建 LogicFlow 实例
  const lf = initLogicFlow()
  // 渲染图表数据
  lf.render(data)
  // 将 LogicFlow 实例保存到 myLf 中
  myLf.value = lf
  // 保存为图片并下载
  document.getElementById('exportImg')!!.addEventListener('click', () => {
    lf.getSnapshot()
  })
  // 数据保存
  document.getElementById('saveFlow')!!.addEventListener('click', () => {
    console.log("数据保存", JSON.stringify(lf.getGraphData(), null, 2))
  })
  // 数据保存
  document.getElementById('importJson')!!.addEventListener('click', () => {
    dialogFormVisible.value = true
  })
  // 监听事件
  const {eventCenter} = lf.graphModel;
  eventCenter.on("node:click", (args) => {
    console.log("节点点击事件", args, args.data.properties);
    if (args.data.type === "flow_end") {
      return
    }
    initFormData(args.data)
    drawer2.value = true
  });
  // 边添加事件
  eventCenter.on("edge:add", (args) => {
    const sourceNode = lf.getDataById(args.data.sourceNodeId)
    // 维护用户任务节点的 目标节点属性
    if(sourceNode?.type == FlowNodeTypeEnum.USER_TASK){
      myLf.value.updateAttributes(args.data.sourceNodeId, {
        properties: {
          ...sourceNode.properties,
          targetNodeId: args.data.targetNodeId,
        }
      })
    }
  });
  // 边点击事件
  eventCenter.on("edge:click", (args) => {
    console.log("edge:click 边点击事件", args, args.data);
    const node = lf.getDataById(args.data.sourceNodeId)
    if(node?.type == FlowNodeTypeEnum.PARALLEL_GATEWAY || node?.type == FlowNodeTypeEnum.EXCLUSIVE_GATEWAY){
      console.log("边点击事件", args, args.data);
      initFormData2(args.data)
      drawer2.value = true
    }
  });
  eventCenter.on("edge:dbclick", (args) => {
    console.log("边双击", args.data.id);
  });
})
</script>

<style>
#container {
  margin-top: 5px;
  /* 容器宽度 */
  width: 100%;
  /* 容器高度 */
  height: 100%;
}
</style>